import { fluTempPoints, setTempPoints } from '../config';
import { N_cPLDetails, Tsrv, ifs, ts } from './base';
import { T_productLog } from './productLog';

class T_cmd extends T_productLog {
  // 挂组生成标志
  // public hangGroupFlag: string[] = ['my855'];
  public hangGroupFlag: string[] = ['myTest001'];

  // 物理编号
  private physicalNum: string[] = ['my357'];

  // 零件编码
  private partCode: string[] = ['my862', 'my863', 'my864', 'my865', 'my866'];

  // 零件数量
  private partNum: string[] = ['my867', 'my868', 'my869', 'my870', 'my871'];

  // 写工艺参数成功或失败
  private writeSuccess: string[] = ['my1805', 'my1806'];

  // 服务器下发参数标志
  private writeFlag: string[] = ['my1807'];

  // 挂组加工完成后下线标志
  public writeHangGroup: string[] = ['my1808'];

  // 下料完成的挂组ID号
  public writeHangGroupId: string[] = ['my1809'];

  // 32个槽详细点位信息
  // public slotCodeDetail: N_cPLDetails.I_slotCodeDetail[] = [];

  // 判断合法性校验是否已经完成
  // public legalStatus = N_cPLDetails.V_reqStatus.NOTSTART;

  // 当前plc校验行id
  public currentPlcId: string = '';

  // 等待校验行
  // public waitPlcData = [];

  private headId: string = '';

  // 挂组plc校验结果
  private hangGroupPlcResult = {};

  // 铬酸阳极化实温
  private cAtempRange = 0;

  // 挂组状态
  private hangGroupStatus = {
    '0': '等待',
    '1': '工艺已定',
    '2': '准备就绪',
    '3': '排程中',
    '4': '已排程',
    '5': '加工中',
    '6': '加工完毕'
  };

  // 设定温度点位
  private setTempPoint: string[] = setTempPoints();

  // 波动温度点位
  private fluTempPoint: string[] = fluTempPoints();

  // 挂组指定工艺
  private hgSpecProcess: N_cPLDetails.hgSpecProcess[] = [];

  public startTask() {
    this.task.addTask(this.readData);
    this.task.startTask();
    this.isOpenTask = true;
  }

  public stopTask() {
    this.task.delTask(this.readData);
    // this.scheduleTask.delTask(this.getTaskStatus);
    this.task.stopTask();
    // this.scheduleTask.stopTask();
    this.isOpenTask = false;
  }

  private readData = () => {
    this.readPlcData(this.ecDetCodeList).then(data => {
      if (typeof data === 'boolean') return;
      // 行车处于自动运行标志且无暂停无报警
      // this.isAutoProduce =
      //   data['my800'].v &&
      //   data['my818'].v &&
      //   !data['my498'].v &&
      //   !data['my499'].v &&
      //   !data['my801'].v &&
      //   !data['my819'].v;
      for (const [key, value] of Object.entries(data)) {
        if (typeof value.v === 'boolean' && value.v) {
          switch (key) {
            case this.hangGroupFlag[0]:
              // 挂组生成标志
              this.handleHangGroupFlag(value.v);
              break;
            case 'my1806':
              // 写工艺参数失败，状态退回等待，并提示PLC校验失败，请检查后重试
              this.plcResultHandle('my1806', 0);
              break;
            case 'my1805':
              // 写工艺参数成功，状态改为已完成，并通知my1805
              this.plcResultHandle('my1805', 2);
              break;
            case 'my1808':
              // 挂组状态更新为加工完毕，并通知my1808
              this.updateHangGroupStatusToFinished(data);
              break;
            default:
              break;
          }
        }
      }

      // 获取当前缓存位挂组状态
      this.getCacheHGStatus(data);

      // 监听槽温度变化
      this.listenSlotTemp(data);
    });
  };

  // 监听各槽温度
  private listenSlotTemp(data: N_cPLDetails.I_readResp['data']) {
    const writeData = [];
    this.updateChromicAcidTankTemp();

    const hangGroupItem = this.findMinNonZeroCacheItem();
    if (hangGroupItem === null) return;

    this.fourCacheInfo.forEach(cache => {
      this.processCacheTemperature(cache, hangGroupItem, data, writeData);
    });

    if (!Tsrv.noValue(writeData)) {
      this.writePlcData(writeData);
    }
  }

  // 更新铬酸槽温度
  private updateChromicAcidTankTemp() {
    this.cAtempRange = this.self.tanks.find(tank => tank.id === 15).params
      .temperature.value as number;
  }

  // 处理单个缓存位的温度检查
  private processCacheTemperature(
    cache: N_cPLDetails.I_cacheInfo,
    hangGroupItem: N_cPLDetails.I_cacheInfo,
    data: N_cPLDetails.I_readResp['data'],
    writeData: any[]
  ) {
    const hgProcess = this.hgSpecProcess.find(
      item => item.hgID === hangGroupItem.hangGroupId.value
    );
    if (!hgProcess) return;

    const allTempsInRange = this.checkAllTemperaturesInRange(hgProcess);
    this.updateCacheStatus(cache, allTempsInRange, data, writeData);
  }

  // 检查所有槽温度是否在范围内
  private checkAllTemperaturesInRange(
    hgProcess: N_cPLDetails.hgSpecProcess
  ): boolean {
    return hgProcess.processPara.every(tp => {
      const slotID = this.getSlotID(tp.tankName);
      const tempParams = this.self.tanks.find(tank => tank.id === slotID);

      if (!tempParams || tempParams.params?.temperature?.value === undefined) {
        this.self.$Message.error('当前槽位无温度电控点，请检查');
        return false;
      }

      const temp = tempParams.params.temperature.value as number;
      const minTemp = tp.setTemp - tp.fluTemp;
      const maxTemp = tp.setTemp + tp.fluTemp;
      return temp >= minTemp && temp <= maxTemp;
    });
  }

  // 更新缓存位状态
  private updateCacheStatus(
    cache: N_cPLDetails.I_cacheInfo,
    allTempsInRange: boolean,
    data: N_cPLDetails.I_readResp['data'],
    writeData: any[]
  ) {
    cache.tempIsSatisfied.value = allTempsInRange;
    const currentStatus = data[cache.tempIsSatisfied.code].v;

    if (allTempsInRange && currentStatus) {
      writeData.push({
        ecDetCode: cache.tempIsSatisfied.code,
        value: false
      });
    } else if (
      !allTempsInRange &&
      !currentStatus &&
      Number(cache.hangGroupId.value) !== 0
    ) {
      writeData.push({
        ecDetCode: cache.tempIsSatisfied.code,
        value: true
      });
    }
  }

  // 找到顺序除0之外最小的缓存位挂组
  private findMinNonZeroCacheItem(): null | N_cPLDetails.I_cacheInfo {
    let minValue = Infinity;
    let minItem = null;
    for (const [key, value] of this.fourCacheInfo) {
      const orderValue = value.cacheOrder.value;
      if (orderValue !== 0 && orderValue < minValue) {
        minValue = orderValue;
        minItem = value;
      }
    }
    return minItem;
  }

  // 匹配槽id
  private getSlotID(slotName: string): number {
    const regex = /\d+/;
    const match = slotName.match(regex);

    if (match) {
      return Number(match[0]);
    }
    return 0;
  }

  private handleHangGroupFlag(value: boolean) {
    if (value) {
      // 将my855写为false,然而请求的缓存数据仍为true,此时不应该重新请求挂组数据,
      // 可以记录将855写为false之后读取仍为true的次数,当次数达到2次时,则可能是写入失败或者仍在队列中未刷新缓存
      if (this.handleException.read.hasWritten) {
        this.handleException.read.count++;
        if (this.handleException.read.count === 2) {
          this.handleException.read.hasWritten = false;
          this.handleException.read.count = 0;
        } else if (this.handleException.read.count < 2) {
          return;
        }
      }
      // 读取数据成功，开始写入数据库，并通知my855
      this.writePlcData(
        [
          {
            ecDetCode: this.hangGroupFlag[0],
            value: 'false'
          }
        ],
        true
      ).then(b => {
        if (b) {
          // 855已经写为false，并已经通知现场挂组生成按钮关闭
          this.handleException.read.hasWritten = true;
          this.beForeinsertData();
        }
      });
    }
  }

  // 挂组状态更新为加工完毕
  private updateHangGroupStatusToFinished(
    data: N_cPLDetails.I_readResp['data']
  ) {
    // // 无加工中的挂组则停止读取my1808,判断条件f_status为5的条数是否为0
    // if (
    //   this.topBaseGrid.cloudData.filter(item => item.f_status === 5).length ===
    //   0
    // ) {
    //   this.ecDetCodeList = this.ecDetCodeList.filter(item => item !== 'my1808');
    //   // Tsrv.myECR.removeEcCodeList('my1808');
    // }
    this.writePlcData([
      {
        ecDetCode: 'my1808',
        value: 'false'
      }
    ]).then(_ => {
      // if (success) {
      // 挂组状态更新为加工完毕
      const hgPhyNum = data[this.writeHangGroupId[0]].v;
      const row = this.topBaseGrid.cloudData.find(
        el => el.physical_num === hgPhyNum
      );
      if (!Tsrv.noValue(row) && row.f_status < 6) {
        const updateData = [
          [
            {
              field: this.filterName.physicalNum,
              value: hgPhyNum
            } as ifs.I_fv,
            {
              field: 'f_status',
              value: 6
            } as ifs.I_fv,
            {
              field: 'end_time',
              value: Tsrv.utils.toDateString(new Date())
            } as ifs.I_fv
          ]
        ];
        this.modifyData(
          this.tableName.pLDetails,
          this.filterName.physicalNum,
          updateData
        ).then(r => {
          this.self.sendLogOut(`挂组${hgPhyNum}已加工完毕`);
          this.updateTaskInfo();
          // 记录挂组日志
          const processRow = [
            [
              {
                field: 'id',
                value: Tsrv.getSnowIDFmtStr()
              } as ifs.I_fv,
              {
                field: 'master_bill_id',
                value: row.id
              } as ifs.I_fv,
              {
                field: 'title',
                value: '加工完毕'
              } as ifs.I_fv
            ]
          ];
          this.addTableData(this.tableName.hGLog, processRow).then(success1 => {
            if (success1) {
              // this.sendBusEvent(this.commonEvent.hGLogEvent, row);
            }
          });
        });
      }
      // }
    });
  }

  // 读取缓存位挂组状态
  private getCacheHGStatus(data: N_cPLDetails.I_readResp['data']) {
    // 准备就绪挂组
    const readyHgData = [];
    // 加工中挂组
    const processHgData = [];
    // 加工中挂组编号集
    const processHgNum = [];
    // 挂组日志
    const hgLogData = [];
    // 派工单号集
    const dispatchBillIdSet = [];
    this.fourCacheInfo.forEach((value, key) => {
      // 缓存位状态发生变化则更新缓存位信息
      // if (value.hangGroupStatus.value !== data[value.hangGroupStatus.code].v) {
      // 加工中
      if (
        Number(value.hangGroupId.value) !== 0 &&
        data[value.hangGroupId.code].v === 0
      ) {
        // 领走加工的一刻判断当前行车是否自动运行，行车处于自动运行标志且无报警
        this.isAutoProduce =
          data['my800'].v &&
          data['my818'].v &&
          !data['my498'].v &&
          !data['my499'].v;
        // !data['my801'].v &&
        // !data['my819'].v;
        // 如果此时状态为false，并且挂组id也存在变化，则该挂组已送去加工，将状态置为加工中
        if (
          data[value.hangGroupStatus.code].v &&
          data[value.hangGroupId.code].v !== value.hangGroupId.value
        ) {
          const hgInfo = this.topBaseGrid.cloudData.find(
            it => it.physical_num === value.hangGroupId.value
          );

          if (hgInfo && hgInfo.f_status < 5 && hgInfo.f_status >= 0) {
            processHgData.push([
              {
                field: this.filterName.physicalNum,
                value: hgInfo.physical_num
              } as ifs.I_fv,
              {
                field: 'f_status',
                value: 5
              } as ifs.I_fv,
              {
                field: 'begin_time',
                value: Tsrv.utils.toDateString(new Date())
              } as ifs.I_fv,
              {
                field: 'is_automated_produc',
                value: this.isAutoProduce ? 1 : 0
              } as ifs.I_fv
            ]);
            hgLogData.push([
              {
                field: 'id',
                value: Tsrv.getSnowIDFmtStr()
              } as ifs.I_fv,
              {
                field: 'master_bill_id',
                value: hgInfo.physical_num
              } as ifs.I_fv,
              {
                field: 'title',
                value: '开始加工'
              } as ifs.I_fv
            ]);
            processHgNum.push(hgInfo.physical_num);
            // 如果此时行车处于非自动，则修改对应派工单号自动状态
            if (!this.isAutoProduce) {
              dispatchBillIdSet.push([
                {
                  field: 'master_bill_id',
                  value: hgInfo.physical_num
                } as ifs.I_fv,
                {
                  field: 'is_automated_produc',
                  value: this.isAutoProduce ? 1 : 0
                } as ifs.I_fv
              ]);
            }
          }
          // 加工中的工艺无需再记录
          this.hgSpecProcess = this.hgSpecProcess.filter(
            it => it.hgID !== hgInfo.physical_num
          );
        }
      }
      // 新上挂
      if (
        Number(value.hangGroupId.value) === 0 &&
        data[value.hangGroupId.code].v !== 0
      ) {
        // 如果此时该挂组plc已校验成功，则进入准备就绪状态
        const hgInfo = this.topBaseGrid.cloudData.find(
          el => el.physical_num === data[value.hangGroupId.code].v
        );
        if (
          hgInfo &&
          hgInfo.f_status < 2 &&
          this.hangGroupPlcResult[hgInfo.physical_num]
        ) {
          delete this.hangGroupPlcResult[hgInfo.physical_num];
          this.addHGSupplement(
            `挂组${data[value.hangGroupId.code].v}状态变为准备就绪`,
            hgInfo.id
          );
          readyHgData.push([
            {
              field: this.filterName.physicalNum,
              value: data[value.hangGroupId.code].v
            } as ifs.I_fv,
            {
              field: 'f_status',
              value: 2
            } as ifs.I_fv
          ]);
        }

        this.self.sendLogOut(
          `${key}挂组ID更新为${data[value.hangGroupId.code].v}`
        );
        // value.hangGroupStatus.value = data[value.hangGroupStatus.code].v;
        // value.hangGroupId.value = data[value.hangGroupId.code].v;
      }
      value.hangGroupStatus.value = data[value.hangGroupStatus.code].v;
      value.hangGroupId.value = data[value.hangGroupId.code].v;
      // value.cacheOrder.value = data[value.cacheOrder.code].v;顺序号未轮询
    });
    if (!Tsrv.noValue(readyHgData)) {
      this.modifyData(
        this.tableName.pLDetails,
        this.filterName.physicalNum,
        readyHgData
      );
    }
    if (!Tsrv.noValue(processHgData)) {
      this.modifyData(
        this.tableName.pLDetails,
        this.filterName.physicalNum,
        processHgData
      ).then(success => {
        if (success) {
          this.self.sendLogOut(`挂组${processHgNum.join(',')}状态更新为加工中`);
          // 记录挂组日志
          this.addTableData(this.tableName.hGLog, hgLogData).then(success1 => {
            if (success1) {
              // this.sendBusEvent(this.commonEvent.hGLogEvent, this.eventArg);
              this.updateTaskInfo();
            }
          });
        }
      });
    }

    if (!Tsrv.noValue(dispatchBillIdSet)) {
      this.modifyData(
        this.tableName.gZDetails,
        'master_bill_id',
        dispatchBillIdSet
      );
    }
  }

  // 写入数据库前读取挂组与零件信息 并判断是否采集失败
  private beForeinsertData() {
    this.readPlcData(this.physicalNum.concat(this.partCode, this.partNum)).then(
      data1 => {
        if (typeof data1 === 'boolean') return;
        // 判断是否有寄存器点采集失败，如果采集失败则重新读取，
        let flag = false;
        let errCode = '';
        const keys = Object.keys(data1);
        for (let i = 0; i < keys.length; i++) {
          if (!Tsrv.noValue(data1[keys[i]].err)) {
            flag = true;
            errCode = keys[i];
            break;
          }
        }
        if (flag) {
          // 寄存器点采集失败，等待2秒后重新读取
          this.self.sendLogOut({
            content: `${errCode}读取失败，等待2秒后重试`,
            isErr: true
          });
          setTimeout(() => {
            this.beForeinsertData();
          }, 2000);
        } else {
          // 读取数据成功，开始写入数据库
          // 整理好json，写入'produc_line_detail_mgmt'与'hang_group_detail_mamt'两张表中
          this.insertData(data1);
        }
      }
    );
  }

  // plc校验结果处理
  private plcResultHandle(code: 'my1806' | 'my1805', status: 0 | 2) {
    // 挂组的工艺校验成功并且挂组已在缓存位，则进入准备就绪状态
    // this.legalStatus = N_cPLDetails.V_reqStatus.FINISHED;
    this.ecDetCodeList = this.ecDetCodeList.filter(
      item => item !== 'my1806' && item !== 'my1805'
    ); // 清空my1806和my1805
    // Tsrv.myECR.removeEcCodeList(['my1806', 'my1805']);
    this.writePlcData(
      [
        {
          ecDetCode: code,
          value: 'false'
        }
      ],
      true
    );

    // 是否可修改挂组状态
    let canChangeStatus = false;

    let str = '';
    if (status === 0) {
      canChangeStatus = true;
      // 记录当前plc校验状态
      const hgPhyNum = this.topBaseGrid.cloudData.find(
        el => el.id === this.currentPlcId
      ).physical_num;
      this.hangGroupPlcResult[hgPhyNum] = false;

      this.self.$msg(`挂组${hgPhyNum}经PLC校验失败，请检查后重试`);
      this.self.sendLogOut({
        content: `挂组${hgPhyNum}经PLC校验失败，该挂组已退回等待`,
        isErr: true
      });
      str = `挂组${hgPhyNum}经plc校验失败,挂组状态变为${
        this.hangGroupStatus[status.toString()]
      }`;
    } else {
      // 记录当前plc校验状态
      const hgInfo = this.topBaseGrid.cloudData.find(
        el => el.id === this.currentPlcId
      );
      str = `挂组${hgInfo.physical_num}经plc校验成功`;
      this.hangGroupPlcResult[hgInfo.physical_num] = true;
      this.fourCacheInfo.forEach((value, _) => {
        if (
          hgInfo &&
          value.hangGroupId.value === hgInfo.physical_num &&
          hgInfo.f_status < 2
        ) {
          canChangeStatus = true;
          delete this.hangGroupPlcResult[hgInfo.physical_num];
          str = `挂组${hgInfo.physical_num}plc校验成功,挂组状态变为${
            this.hangGroupStatus[status.toString()]
          }`;
        }
      });
      this.self.sendLogOut(`挂组${hgInfo.physical_num}经plc校验成功`);
    }
    if (canChangeStatus) {
      const data = [
        [
          {
            field: 'id',
            value: this.currentPlcId
          } as ifs.I_fv,
          {
            field: 'f_status',
            value: status
          } as ifs.I_fv
        ]
      ];
      this.modifyData(this.tableName.pLDetails, this.filterName.ID, data).then(
        success => {
          if (success) {
            this.addHGSupplement(str, this.currentPlcId);
          }
        }
      );
    }
    // 校验下一组
    // if (!Tsrv.noValue(this.waitPlcData)) {
    //   this.submitPlc(this.waitPlcData[0]);
    //   this.waitPlcData.shift();
    // }
  }

  // 插入数据
  private insertData(data: N_cPLDetails.I_readResp['data']) {
    // 找到数组中my357的v值，对应produc_line_detail_mgmt表的physical_num字段值
    let part_qty: number = 0;
    this.partNum.forEach(item => {
      part_qty += Number(data[item].v);
    });
    this.headId = Tsrv.getSnowIDFmtStr();
    const bpaHeadData: Array<ifs.I_fv> = [
      {
        field: 'id',
        value: this.headId
      } as ifs.I_fv,
      {
        field: this.filterName.physicalNum,
        value: data['my357'].v
      } as ifs.I_fv,
      {
        field: 'master_bill_id',
        value: this.self.formData.id
        // value: '542957916634763264'
      } as ifs.I_fv,
      {
        field: 'is_automated_produc',
        value: this.isAutoProduce ? 1 : 0
      } as ifs.I_fv,
      {
        field: 'process_flow_num',
        value: this.self.formData.process_flow_num
      } as ifs.I_fv,
      {
        field: 'part_qty',
        value: part_qty
      } as ifs.I_fv,
      {
        field: 'upload_status',
        value: 0
      } as ifs.I_fv
    ];
    const bpaBodyData: Array<Array<ifs.I_fv>> = [];
    this.partCode.forEach((item, index) => {
      if (data[item].v !== '') {
        const partData: ifs.I_fv[] = [
          {
            field: 'id',
            value: Tsrv.getSnowIDFmtStr()
          } as ifs.I_fv,
          {
            field: 'master_bill_id',
            value: this.headId
          } as ifs.I_fv,
          {
            field: 'category_number',
            value: data[item].v
          } as ifs.I_fv,
          {
            field: 'qty',
            value: data[this.partNum[index]].v
          } as ifs.I_fv,
          {
            field: 'is_automated_produc',
            value: this.isAutoProduce ? 1 : 0
          } as ifs.I_fv
        ];
        bpaBodyData.push(partData);
      }
    });
    // 插入数据使用bpa插入
    const bpa = new ts.T_bpaArg();
    bpa
      .setHead(this.getBpaHead(bpaHeadData))
      .setBody(this.getBpaBody(bpaBodyData));
    Tsrv.batBill(bpa).then(([b, res, msg]) => {
      if (!msg) {
        this.self.$msg(msg);
      }
      if (!b) {
        this.self.$msg(res.msg);
      } else {
        this.topBaseGrid.GT_editor.addInitFilter({
          field: 'master_bill_id',
          value: this.self.formData.id
        });
        this.topBaseGrid.GT_editor.loadTableData().then(() => {
          this.self.$bus.$emit('UPD_PL_DETAILS');
          this.self.sendLogOut(`挂组${data['my357'].v}上挂完成`);
          this.addHGDetails();
          this.updateTaskInfo();
        });
      }
    });
  }

  private getBpaHead(headInsRec: Array<ifs.I_fv>): ifs.I_bpaHead {
    const o = new ts.T_bpaHead();
    const d = new ts.T_bpaHeadInsRec();
    const afterParams = new ts.T_syncParams();
    const syncData = {
      funName: this.tableName.pLDetails,
      from: 'afterInsert',
      data: {
        id: this.headId,
        insertRecords: headInsRec
      }
    };
    afterParams
      .setApiName('produc_line_detail_mgmt_aft_saves')
      .setUserInfo(Tsrv.getUserInfo())
      .setFunInfo(Tsrv.getFunInfo(this.tableName.pLDetails))
      .setSyncData(syncData);
    d.setAftEvent(afterParams);
    d.setDataRule({} as ifs.I_rule)
      .setFileInfo({})
      .setRowData(...headInsRec);
    o.setInsertRec(d);

    o.setFunName(this.tableName.pLDetails)
      .setLang(this.self.$i18n.locale)
      .setDbType(Tsrv.globalVar.dbType.MYSQL)
      .setTableName(this.tableName.pLDetails);
    return o;
  }

  private getBpaBody(bodyInsRec: Array<Array<ifs.I_fv>>): ifs.I_bpaBody {
    const o = new ts.T_bpaBody();
    o.rule = {} as ifs.I_rule;
    const d = new ts.T_bpaBodyInsRec();
    d.setScope({ field: 'master_bill_id', value: this.headId });
    if (Tsrv.noValue(bodyInsRec)) {
      d.data = [];
    } else {
      bodyInsRec.forEach(item => {
        const baseData = new ts.T_baseData();
        baseData
          .setRowData(...item)
          .setFileInfo({})
          .setDataRule({} as ifs.I_rule);
        d.data.push(baseData);
      });
    }
    o.data.push({
      tableName: this.tableName.gZDetails,
      dbType: Tsrv.globalVar.dbType.MYSQL,
      insertRecords: d
    });
    return o;
  }

  // 新增挂组明细
  private addHGDetails() {
    const data = [
      [
        {
          field: 'id',
          value: Tsrv.getSnowIDFmtStr()
        } as ifs.I_fv,
        {
          field: 'hang_group_id',
          value: this.headId
        } as ifs.I_fv,
        {
          field: 'master_bill_id',
          value: this.self.currentOpenLineInfo.id
        } as ifs.I_fv
      ]
    ];
    this.addTableData(this.tableName.hGDetails, data);
  }

  // 新增挂组补充信息
  private addHGSupplement(title: string, matser_bill_id) {
    const rows = [
      [
        {
          field: 'id',
          value: Tsrv.getSnowIDFmtStr()
        } as ifs.I_fv,
        {
          field: 'master_bill_id',
          value: matser_bill_id
        } as ifs.I_fv,
        {
          field: 'title',
          value: title
        } as ifs.I_fv
      ]
    ];
    this.addTableData(this.tableName.hGSupplementInfo, rows);
  }

  // 提交plc校验
  public submitPlc(params: N_cPLDetails.I_receiveParams) {
    // 模拟返回参数
    const codes: N_cPLDetails.I_writeCodeRes[] = [
      {
        ecDetCode: this.writeFlag[0],
        value: 'true'
      }
    ];
    params.ecDetCodes.forEach(el => {
      const value = isNaN(Number(el.value))
        ? el.value
        : Math.round(Number(el.value) * el.conversionRate);
      codes.push({
        ecDetCode: el.ecDetCode,
        value: String(value)
      });
    });

    this.currentPlcId = params.currentRowID;
    const hgID = this.topBaseGrid.cloudData.find(
      it => it.id === params.currentRowID
    ).physical_num;

    if (this.hgSpecProcess.find(it => it.hgID === hgID) === undefined) {
      const processPara = {
        hgID,
        processPara: []
      };
      params.ecDetCodes.forEach(el => {
        if (this.setTempPoint.includes(el.ecDetCode)) {
          processPara.processPara.push({
            tankName: el.tankName,
            setTemp: el.value
          });
        }
        if (this.fluTempPoint.includes(el.ecDetCode)) {
          // processPara.processPara
          if (
            processPara.processPara.find(it => it.tankName === el.tankName) ===
            undefined
          ) {
            processPara.processPara.push({
              tankName: el.tankName,
              setTemp: el.value
            });
          } else {
            processPara.processPara.find(
              it => it.tankName === el.tankName
            ).fluTemp = el.value;
          }
        }
      });
      this.hgSpecProcess.push(processPara);
    }

    this.writePlcData(codes)
      .then(_ => {
        this.ecDetCodeList.push(...this.writeSuccess);
        // Tsrv.myECR.addEcCodeList(this.writeSuccess);
        // this.legalStatus = N_cPLDetails.V_reqStatus.RUNNING;
        const str = `当前挂组状态变为${this.hangGroupStatus['1']}`;
        this.addHGSupplement(str, this.currentPlcId);
      })
      .catch(_ => {
        const data = [
          [
            {
              field: 'id',
              value: this.currentPlcId
            } as ifs.I_fv,
            {
              field: 'f_status',
              value: 0
            } as ifs.I_fv
          ]
        ];
        this.modifyData(this.tableName.pLDetails, this.filterName.ID, data);
      });
  }

  public updateTaskInfo() {
    const taskInfo = {
      doneCount: this.topBaseGrid.cloudData.filter(el => el.f_status === 6)
        .length,
      workCount: this.topBaseGrid.cloudData.filter(el => el.f_status === 5)
        .length,
      waitCount: this.topBaseGrid.cloudData.filter(el => el.f_status <= 4)
        .length
    };
    this.self.$bus.$emit(this.commonEvent.updateTaskInfo, taskInfo);
  }

  // 排程前处理
  public beforeSchedule(val: Array<any>) {
    const readyData = val.filter(el => el.f_status === 2);
    const processingData = val.filter(el => el.f_status === 5);

    this.logScheduleStart(readyData.length, processingData.length);

    if (processingData.length === 0 && readyData.length === 1) {
      this.handleSingleReadyGroup(readyData[0]);
    } else if (processingData.length > 0 && readyData.length >= 1) {
      this.handleMixedGroups(readyData, processingData);
    } else if (processingData.length === 0 && readyData.length > 1) {
      this.handleMultipleReadyGroups(readyData);
    }
  }

  private logScheduleStart(readyCount: number, processingCount: number) {
    this.self.sendLogOut(
      `开始排程处理，准备就绪挂组:${readyCount}，加工中挂组:${processingCount}`
    );
  }

  private handleSingleReadyGroup(readyGroup: any) {
    // 其他缓存位加工顺序置0处理
    const data = [];
    this.fourCacheInfo.forEach((value, _) => {
      if (value.hangGroupId.value === readyGroup.physical_num) {
        value.cacheOrder.value = 1;
        this.writeCacheOrder(
          value.cacheOrder.code,
          '1',
          readyGroup.physical_num
        );
      } else {
        value.cacheOrder.value = 0;
        data.push({
          ecDetCode: value.cacheOrder.code,
          value: '0'
        });
      }
    });
    this.writePlcData(data);
  }

  private writeCacheOrder(code: string, value: string, groupId: string) {
    const writeData = [{ ecDetCode: code, value }];
    return this.writePlcData(writeData).then(success => {
      if (success) {
        this.self.sendLogOut(`挂组${groupId}缓存位加工顺序为${value}`);
      }
      return success;
    });
  }

  private handleMixedGroups(readyData: any[], processingData: any[]) {
    const hangGroups = [
      ...this.createHangGroupItems(readyData, 0),
      ...this.createHangGroupItems(processingData, 1)
    ];
    this.startSchedule(hangGroups);
  }

  private handleMultipleReadyGroups(readyData: any[]) {
    const hangGroups = this.createHangGroupItems(readyData, 0);
    this.startSchedule(hangGroups);
  }

  private createHangGroupItems(groups: any[], status: number) {
    return groups.map(item => ({
      physicalNum: item.physical_num,
      status,
      time: item.create_time
    }));
  }

  // 开启排程计算
  public startSchedule(hangGroupList: Array<any>) {
    // 数组根据time字段排序
    const list = hangGroupList.sort((a, b) => {
      return new Date(a.time).getTime() - new Date(b.time).getTime();
    });
    for (const el of list) {
      delete el.time;
    }
    // 调用api
    const gridFunInfo = Tsrv.getFunInfo(this.tableName.pLDetails);
    const params = () => {
      return {
        funName: 'cPLDetails',
        title: 'customFun',
        from: 'cPLDetails',
        data: {
          hangGroups: list,
          slotTemp: {
            slotName: '585792609139363840', // 铬酸工序id号
            currentTemp: this.cAtempRange
          }
        }
      };
    };
    // 调用api
    Tsrv.doEvent('my_simulate_the_process_flow', gridFunInfo, params).then(
      res => {
        if (res.isErr()) {
          this.self.$msg(res.errmsg);
          // 将准备就绪挂组状态退回到等待状态
          const data = [];
          // 只回退准备就绪挂组状态
          hangGroupList.forEach(item => {
            if (item.status === 0) {
              data.push([
                {
                  field: this.filterName.physicalNum,
                  value: item.physicalNum
                } as ifs.I_fv,
                {
                  field: 'f_status',
                  value: 0
                } as ifs.I_fv
              ]);
            }
          });
          this.modifyData(
            this.tableName.pLDetails,
            this.filterName.physicalNum,
            data
          );
        } else {
          const returnData = res.getReturnData('conf');
          const data = returnData.res.data;
          const processSeq = [];
          const writeData = [];
          data.hangGroups.forEach(item => {
            this.fourCacheInfo.forEach((value, _) => {
              // 返回的挂组物理编号是字符串
              if (value.hangGroupId.value === Number(item.physicalNum)) {
                value.cacheOrder.value = item.processSequence;
                writeData.push({
                  ecDetCode: value.cacheOrder.code,
                  value: String(item.processSequence)
                });
                processSeq.push(
                  `${item.physicalNum} : ${item.processSequence}`
                );
              }
            });
          });

          const nums = data.hangGroups.map(el => Number(el.physicalNum));
          this.fourCacheInfo.forEach((value, _) => {
            if (!nums.includes(value.hangGroupId.value)) {
              writeData.push({
                ecDetCode: value.cacheOrder.code,
                value: '0'
              });
            }
          });

          const orderVal = processSeq.join('，');

          // 提示加工顺序
          this.self.sendLogOut(`本次加工顺序为${orderVal}`);

          // 加工顺序写入plc
          this.writePlcData(writeData).then(success => {
            if (success) {
              const defaultTime = this.changeTimeFormat(data.defaultTime, 1);
              const scheduleTime = this.changeTimeFormat(data.scheduleTime, 1);
              const seconds =
                Number(data.defaultTime) - Number(data.scheduleTime);
              const saveTime = this.changeTimeFormat(seconds, 1);
              const message = `本次默认加工时长为${defaultTime}，排程计算加工时长为${scheduleTime}，预计节省时间为${saveTime}`;
              this.self.sendLogOut(message);
              // 记录排程结果到日志
              this.recordScheLog(orderVal, defaultTime, scheduleTime, saveTime);
            }
          });
        }
      }
    );
  }

  // 记录排程日志
  private recordScheLog(
    orderVal: string,
    defaultTime: string,
    scheduleTime: string,
    saveTime: string
  ) {
    const rows = [
      [
        {
          field: 'title',
          value: orderVal
        } as ifs.I_fv,
        {
          field: 'default_process_times',
          value: defaultTime
        } as ifs.I_fv,
        {
          field: 'sche_process_times',
          value: scheduleTime
        } as ifs.I_fv,
        {
          field: 'expect_save_times',
          value: saveTime
        } as ifs.I_fv
      ]
    ];
    this.addTableData(this.tableName.scheRecordLog, rows);
  }
}
interface I_cmd extends T_cmd {}
export { I_cmd, T_cmd };
